home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / Source / Chapter 4 / Engine / Engine.cpp next >
Encoding:
C/C++ Source or Header  |  2005-03-29  |  8.2 KB  |  272 lines

  1. //-----------------------------------------------------------------------------
  2. // Engine.h implementation.
  3. // Refer to the Engine.h interface for more details.
  4. //
  5. // Programming a Multiplayer First Person Shooter in DirectX
  6. // Copyright (c) 2004 Vaughan Young
  7. //-----------------------------------------------------------------------------
  8. #include "Engine.h"
  9.  
  10. //-----------------------------------------------------------------------------
  11. // Globals
  12. //-----------------------------------------------------------------------------
  13. Engine *g_engine = NULL;
  14.  
  15. //-----------------------------------------------------------------------------
  16. // Handles Windows messages.
  17. //-----------------------------------------------------------------------------
  18. LRESULT CALLBACK WindowProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
  19. {
  20.     switch( msg )
  21.     {
  22.         case WM_ACTIVATEAPP:
  23.             g_engine->SetDeactiveFlag( !wparam );
  24.             return 0;
  25.  
  26.         case WM_DESTROY:
  27.             PostQuitMessage( 0 );
  28.             return 0;
  29.  
  30.         default:
  31.             return DefWindowProc( wnd, msg, wparam, lparam );
  32.     }
  33. }
  34.  
  35. //-----------------------------------------------------------------------------
  36. // The engine class constructor.
  37. //-----------------------------------------------------------------------------
  38. Engine::Engine( EngineSetup *setup )
  39. {
  40.     // Indicate that the engine is not yet loaded.
  41.     m_loaded = false;
  42.  
  43.     // If no setup structure was passed in, then create a default one.
  44.     // Otehrwise, make a copy of the passed in structure.
  45.     m_setup = new EngineSetup;
  46.     if( setup != NULL )
  47.         memcpy( m_setup, setup, sizeof( EngineSetup ) );
  48.  
  49.     // Store a pointer to the engine in a global variable for easy access.
  50.     g_engine = this;
  51.  
  52.     // Prepare and register the window class.
  53.     WNDCLASSEX wcex;
  54.     wcex.cbSize        = sizeof( WNDCLASSEX );
  55.     wcex.style         = CS_CLASSDC;
  56.     wcex.lpfnWndProc   = WindowProc;
  57.     wcex.cbClsExtra    = 0;
  58.     wcex.cbWndExtra    = 0;
  59.     wcex.hInstance     = m_setup->instance;
  60.     wcex.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
  61.     wcex.hCursor       = LoadCursor( NULL, IDC_ARROW );
  62.     wcex.hbrBackground = NULL;
  63.     wcex.lpszMenuName  = NULL;
  64.     wcex.lpszClassName = "WindowClass";
  65.     wcex.hIconSm       = LoadIcon( NULL, IDI_APPLICATION );
  66.     RegisterClassEx( &wcex );
  67.  
  68.     // Initialise the COM using multithreaded concurrency.
  69.     CoInitializeEx( NULL, COINIT_MULTITHREADED );
  70.  
  71.     // Create the window and retrieve a handle to it.
  72.     // Note: Later the window will be created using a windowed/fullscreen flag.
  73.     m_window = CreateWindow( "WindowClass", m_setup->name, WS_OVERLAPPED, 0, 0, 800, 600, NULL, NULL, m_setup->instance, NULL );
  74.  
  75.     // Create the linked lists of states.
  76.     m_states = new LinkedList< State >;
  77.     m_currentState = NULL;
  78.  
  79.     // Create the resource managers.
  80.     m_scriptManager = new ResourceManager< Script >;
  81.  
  82.     // Create the input object.
  83.     m_input = new Input( m_window );
  84.  
  85.     // Seed the random number generator with the current time.
  86.     srand( timeGetTime() );
  87.  
  88.     // Allow the application to perform any state setup now.
  89.     if( m_setup->StateSetup != NULL )
  90.         m_setup->StateSetup();
  91.  
  92.     // The engine is fully loaded and ready to go.
  93.     m_loaded = true;
  94. }
  95.  
  96. //-----------------------------------------------------------------------------
  97. // The engine class destructor.
  98. //-----------------------------------------------------------------------------
  99. Engine::~Engine()
  100. {
  101.     // Ensure the engine is loaded.
  102.     if( m_loaded == true )
  103.     {
  104.         // Destroy the states linked lists.
  105.         if( m_currentState != NULL )
  106.             m_currentState->Close();
  107.         SAFE_DELETE( m_states );
  108.  
  109.         // Destroy everything.
  110.         SAFE_DELETE( m_input );
  111.         SAFE_DELETE( m_scriptManager );
  112.     }
  113.  
  114.     // Uninitialise the COM.
  115.     CoUninitialize();
  116.  
  117.     // Unregister the window class.
  118.     UnregisterClass( "WindowClass", m_setup->instance );
  119.  
  120.     // Destroy the engine setup structure.
  121.     SAFE_DELETE( m_setup );
  122. }
  123.  
  124. //-----------------------------------------------------------------------------
  125. // Enters the engine into the main processing loop.
  126. //-----------------------------------------------------------------------------
  127. void Engine::Run()
  128. {
  129.     // Ensure the engine is loaded.
  130.     if( m_loaded == true )
  131.     {
  132.         // Show the window.
  133.         ShowWindow( m_window, SW_NORMAL );
  134.  
  135.         // Used to retrieve details about the viewer from the application.
  136.         ViewerSetup viewer;
  137.  
  138.         // Enter the message loop.
  139.         MSG msg;
  140.         ZeroMemory( &msg, sizeof( MSG ) );
  141.         while( msg.message != WM_QUIT )
  142.         {
  143.             if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  144.             {
  145.                 TranslateMessage( &msg );
  146.                 DispatchMessage( &msg );
  147.             }
  148.             else if( !m_deactive )
  149.             {
  150.                 // Calculate the elapsed time.
  151.                 unsigned long currentTime = timeGetTime();
  152.                 static unsigned long lastTime = currentTime;
  153.                 float elapsed = ( currentTime - lastTime ) / 1000.0f;
  154.                 lastTime = currentTime;
  155.  
  156.                 // Update the input object, reading the keyboard and mouse.
  157.                 m_input->Update();
  158.  
  159.                 // Check if the user wants to make a forced exit.
  160.                 if( m_input->GetKeyPress( DIK_F1 ) )
  161.                     PostQuitMessage( 0 );
  162.  
  163.                 // Request the viewer from the current state, if there is one.
  164.                 if( m_currentState != NULL )
  165.                     m_currentState->RequestViewer( &viewer );
  166.  
  167.                 // Update the current state (if there is one), taking state
  168.                 // changes into account.
  169.                 m_stateChanged = false;
  170.                 if( m_currentState != NULL )
  171.                     m_currentState->Update( elapsed );
  172.                 if( m_stateChanged == true )
  173.                     continue;
  174.             }
  175.         }
  176.     }
  177.  
  178.     // Destroy the engine.
  179.     SAFE_DELETE( g_engine );
  180. }
  181.  
  182. //-----------------------------------------------------------------------------
  183. // Returns the window handle.
  184. //-----------------------------------------------------------------------------
  185. HWND Engine::GetWindow()
  186. {
  187.     return m_window;
  188. }
  189.  
  190. //-----------------------------------------------------------------------------
  191. // Sets the deactive flag.
  192. //-----------------------------------------------------------------------------
  193. void Engine::SetDeactiveFlag( bool deactive )
  194. {
  195.     m_deactive = deactive;
  196. }
  197.  
  198. //-----------------------------------------------------------------------------
  199. // Adds a state to the engine.
  200. //-----------------------------------------------------------------------------
  201. void Engine::AddState( State *state, bool change )
  202. {
  203.     m_states->Add( state );
  204.  
  205.     if( change == false )
  206.         return;
  207.  
  208.     if( m_currentState != NULL )
  209.         m_currentState->Close();
  210.  
  211.     m_currentState = m_states->GetLast();
  212.     m_currentState->Load();
  213. }
  214.  
  215. //-----------------------------------------------------------------------------
  216. // Removes a state from the engine
  217. //-----------------------------------------------------------------------------
  218. void Engine::RemoveState( State *state )
  219. {
  220.     m_states->Remove( &state );
  221. }
  222.  
  223. //-----------------------------------------------------------------------------
  224. // Changes processing to the state with the specified ID.
  225. //-----------------------------------------------------------------------------
  226. void Engine::ChangeState( unsigned long id )
  227. {
  228.     // Iterate through the list of states and find the new state to change to.
  229.     m_states->Iterate( true );
  230.     while( m_states->Iterate() != NULL )
  231.     {
  232.         if( m_states->GetCurrent()->GetID() == id )
  233.         {
  234.             // Close the old state.
  235.             if( m_currentState != NULL )
  236.                 m_currentState->Close();
  237.  
  238.             // Set the new current state and load it.
  239.             m_currentState = m_states->GetCurrent();
  240.             m_currentState->Load();
  241.  
  242.             // Indicate that the state has changed.
  243.             m_stateChanged = true;
  244.  
  245.             break;
  246.         }
  247.     }
  248. }
  249.  
  250. //-----------------------------------------------------------------------------
  251. // Returns a pointer to the current state.
  252. //-----------------------------------------------------------------------------
  253. State *Engine::GetCurrentState()
  254. {
  255.     return m_currentState;
  256. }
  257.  
  258. //-----------------------------------------------------------------------------
  259. // Returns a pointer to the script manager.
  260. //-----------------------------------------------------------------------------
  261. ResourceManager< Script > *Engine::GetScriptManager()
  262. {
  263.     return m_scriptManager;
  264. }
  265.  
  266. //-----------------------------------------------------------------------------
  267. // Returns a pointer to the input object.
  268. //-----------------------------------------------------------------------------
  269. Input *Engine::GetInput()
  270. {
  271.     return m_input;
  272. }